/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.document.rpc;

import cn.hutool.core.io.FileUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.je.common.base.document.FileBound;
import com.je.common.base.document.FileCopyDTO;
import com.je.common.base.document.InternalFileBO;
import com.je.common.base.document.InternalFileUpload;
import com.je.common.base.service.rpc.DocumentInternalRpcService;
import com.je.common.base.util.JEUUID;
import com.je.common.base.util.StringUtil;
import org.apache.servicecomb.common.rest.HttpTransportContext;
import org.apache.servicecomb.foundation.vertx.http.ReadStreamPart;
import org.apache.servicecomb.provider.pojo.RpcReference;
import org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;
import org.apache.servicecomb.swagger.invocation.context.ContextUtils;
import org.apache.servicecomb.swagger.invocation.context.TransportContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

@Service
public class DocumentInternalRpcServiceImpl implements DocumentInternalRpcService {

    @RpcReference(microserviceName = "document",schemaId = "documentInternalRpcService")
    private DocumentInternalRpcService documentInternalRpcService;
    @Autowired
    private Environment environment;

    @Override
    public InternalFileBO saveSingleFile(InternalFileUpload fileUploadFile, File file, String userId) {
        return documentInternalRpcService.saveSingleFile(fileUploadFile,file,userId);
    }

    @Override
    public InternalFileBO saveSingleFileWithMetadata(InternalFileUpload fileUploadFile, File file, String userId, JSONObject metadata) {
        return documentInternalRpcService.saveSingleFileWithMetadata(fileUploadFile,file,userId,metadata);
    }

    @Override
    public InternalFileBO saveSingleFileWithBucket(InternalFileUpload fileUploadFile, File file, String userId, String bucket) {
        return documentInternalRpcService.saveSingleFileWithBucket(fileUploadFile,file,userId,bucket);
    }

    @Override
    public InternalFileBO saveSingleFileWithMetadataAndBucket(InternalFileUpload fileUploadFile, File file, String userId, JSONObject metadata, String bucket) {
        return documentInternalRpcService.saveSingleFileWithMetadataAndBucket(fileUploadFile,file,userId,metadata,bucket);
    }

    @Override
    public List<InternalFileBO> saveMultiFile(List<InternalFileUpload> fileUploadFiles, List<File> files, String userId) {
        return documentInternalRpcService.saveMultiFile(fileUploadFiles,files,userId);
    }

    @Override
    public List<InternalFileBO> saveMultiFileWithMetadata(List<InternalFileUpload> fileUploadFiles, List<File> files, String userId, JSONObject metadata) {
        return documentInternalRpcService.saveMultiFileWithMetadata(fileUploadFiles,files,userId,metadata);
    }

    @Override
    public List<InternalFileBO> saveMultiFileWithBucket(List<InternalFileUpload> fileUploadFiles, List<File> files, String userId, String bucket) {
        return documentInternalRpcService.saveMultiFileWithBucket(fileUploadFiles,files,userId,bucket);
    }

    @Override
    public List<InternalFileBO> saveMultiFileWithMetadataAndBucket(List<InternalFileUpload> fileUploadFiles, List<File> files, String userId, JSONObject metadata, String bucket) {
        return documentInternalRpcService.saveMultiFileWithMetadataAndBucket(fileUploadFiles,files,userId,metadata,bucket);
    }

    @Override
    public List<InternalFileBO> saveMultiFileWithMetadataAndBucketToDestDir(List<InternalFileUpload> fileUploadFiles, List<File> files, String userId, JSONObject metadata, String bucket, String dir) {
        return documentInternalRpcService.saveMultiFileWithMetadataAndBucketToDestDir(fileUploadFiles,files,userId,metadata,bucket,dir);
    }

    @Override
    public InternalFileBO boundSingleFile(FileBound fileBoundFile, String userId, JSONObject metadata, String bucket) {
        return documentInternalRpcService.boundSingleFile(fileBoundFile,userId,metadata,bucket);
    }

    @Override
    public List<InternalFileBO> boundFile(List<FileBound> fileBounds, String userId, JSONObject metadata, String bucket) {
        return documentInternalRpcService.boundFile(fileBounds,userId,metadata,bucket);
    }

    @Override
    public void saveFileMetadataWithFileKeys(String userId, JSONObject metadata, List<String> fileKeys) {
        documentInternalRpcService.saveFileMetadataWithFileKeys(userId,metadata,fileKeys);
    }

    @Override
    public void saveFileMetadataWithRelIdAndFileId(String userId, JSONObject metadata, String relId, String fileId) {
        documentInternalRpcService.saveFileMetadataWithRelIdAndFileId(userId,metadata,relId,fileId);
    }

    @Override
    public void updateMetadataByKey(String fileKey, String newRelName, JSONObject metadata, String userId) {
        documentInternalRpcService.updateMetadataByKey(fileKey,newRelName,metadata,userId);
    }

    @Override
    public JSONObject selectFileMetadataByKey(String fileKey) {
        return documentInternalRpcService.selectFileMetadataByKey(fileKey);
    }

    @Override
    public InternalFileBO editByFileKey(String fileKey, File file, String userId) {
        return documentInternalRpcService.editByFileKey(fileKey,file,userId);
    }

    @Override
    public InternalFileBO copyRelByKey(String fileKey, String newRelName, JSONObject metadata, String userId) {
        return documentInternalRpcService.copyRelByKey(fileKey,newRelName,metadata,userId);
    }

    @Override
    public void delFilesByKey(List<String> fileKeys, String userId) {
        documentInternalRpcService.delFilesByKey(fileKeys,userId);
    }

    @Override
    public boolean exists(String fileKey) {
        return documentInternalRpcService.exists(fileKey);
    }

    @Override
    public InternalFileBO selectFileByKey(String fileKey) {
        return documentInternalRpcService.selectFileByKey(fileKey);
    }

    @Override
    public InternalFileBO selectFileByKeyAndVersion(String fileKey, String version) {
        return documentInternalRpcService.selectFileByKeyAndVersion(fileKey,version);
    }

    @Override
    public List<InternalFileBO> selectFileListByKey(List<String> keys) {
        return documentInternalRpcService.selectFileListByKey(keys);
    }

    @Override
    public List<InternalFileBO> selectFileByMetadata(JSONObject metadataQuery) {
        return documentInternalRpcService.selectFileByMetadata(metadataQuery);
    }

    @Override
    public List<InternalFileBO> selectFileFullByMetadata(JSONObject metadataQuery) {
        return documentInternalRpcService.selectFileFullByMetadata(metadataQuery);
    }

    @Override
    public File readThumbnail(String fileKey) {
        String url ="cse://document/je/api/document/readThumbnailStream?fileKey="+fileKey;
        return  getFileByfileKey(url,"thumbnail");
    }

    @Override
    public File readFile(String fileKey) {
        String url ="cse://document/je/api/document/readFileStream?fileKey="+fileKey;
        File file =  getFileByfileKey(url,null);
        return file;
    }

    private File getFileByfileKey(String url,String type) {
        String tempDir = environment.getProperty("servicecomb.downloads.directory");
        TransportContext transportContext = ContextUtils.getInvocationContext().getTransportContext();
        HttpTransportContext httpTransportContext = (HttpTransportContext) transportContext;
        HttpServletRequest request = httpTransportContext.getRequestEx();
        RestTemplate restTemplate = RestTemplateBuilder.create();
        ReadStreamPart readStreamPart = restTemplate.postForObject(url,
                request, ReadStreamPart.class);
//        String destDir = tempDir + File.separator + readStreamPart.getSubmittedFileName();
//        if(FileUtil.exist(destDir)){
//            FileUtil.del(destDir);
//        }
        String filePath ="";
        String suffix=getFileTypeSuffix(readStreamPart.getSubmittedFileName());
        if("thumbnail".equals(type)){
            filePath =tempDir + File.separator +"/thumbnail/"+ JEUUID.uuid()+"."+suffix;
        }else{
            filePath = tempDir + File.separator + JEUUID.uuid()+"."+suffix;
        }
//        String filePath ="";
//        if("thumbnail".equals(type)){
//            filePath =tempDir + File.separator +"/thumbnail/"+ readStreamPart.getSubmittedFileName();
//        }else{
//            filePath = tempDir + File.separator + readStreamPart.getSubmittedFileName();
//        }
        CompletableFuture<File> future = readStreamPart.saveToFile(filePath);
        File file = null;
        try {
            file = future.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        return file;
    }
    public String getFileTypeSuffix(String filePath){
        String fileType="";
        if(StringUtil.isNotEmpty(filePath)){
            int lastIndex=filePath.lastIndexOf(".");
            if(lastIndex!=-1){
                fileType=filePath.substring(lastIndex+1);
            }
        }
        return fileType;
    }
    @Override
    public List<InternalFileBO> selectAllVersionFiles(String fikeKey) {
        return documentInternalRpcService.selectAllVersionFiles(fikeKey);
    }

    @Override
    public InternalFileBO selectVersionFile(String fikeKey, int version) {
        return documentInternalRpcService.selectVersionFile(fikeKey,version);
    }

    @Override
    public void updateFiledFile(String userId, String tableCode, String pkValue, String fieldCode, List<String> usedFileKey) {
        documentInternalRpcService.updateFiledFile(userId,tableCode,pkValue,fieldCode,usedFileKey);
    }

    @Override
    public List<FileCopyDTO> copyFiles(String userId, String tableCode, String pkValue, String fieldCode, String newPkValue) {
        return documentInternalRpcService.copyFiles(userId,tableCode,pkValue,fieldCode,newPkValue);
    }

    @Override
    public List<FileCopyDTO> copyFilesWithFuncCode(String userId, String tableCode, String pkValue, String fieldCode, String newPkValue, String newFuncCode, String newTableCode, String newFiledCode) {
        return documentInternalRpcService.copyFilesWithFuncCode(userId,tableCode,pkValue,fieldCode,newPkValue,newFuncCode,newTableCode,newFiledCode);
    }

    @Override
    public void deleteFiles(String tableCode, String pkValues, String userId) {
        documentInternalRpcService.deleteFiles(tableCode,pkValues,userId);
    }

    @Override
    public void deleteFilesWithFieldCodes(String tableCode, String pkValues, String fieldCodes, String userId) {
        documentInternalRpcService.deleteFilesWithFieldCodes(tableCode,pkValues,fieldCodes,userId);
    }

    @Override
    public void deleteFilesWithFieldCodesAndUploadTypes(String tableCode, String pkValues, String fieldCodes, String uploadTypes, String userId) {
        documentInternalRpcService.deleteFilesWithFieldCodesAndUploadTypes(tableCode,pkValues,fieldCodes,uploadTypes,userId);
    }

    @Override
    public JSONArray listFilesMeta(String bucket, String path) {
        return documentInternalRpcService.listFilesMeta(bucket,path);
    }


    @Override
    public void deleteByFileKeys(List<String> fileKeys, String userId) {
        documentInternalRpcService.deleteByFileKeys(fileKeys, userId);
    }
}
